﻿using System;
using System.Collections.Generic;
using System.Linq;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Electrical;
using Autodesk.Revit.DB.ExtensibleStorage;
using Autodesk.Revit.DB.Mechanical;
using Autodesk.Revit.DB.Plumbing;
using YArchitech.Revit;
using HYRevitCode.ElementSearchUtility.LinkDocumentSuite;

namespace YArchitech.HVAC
{
	internal class QuickMarkManager
	{
		public static bool CheckDimension(IList<FilterType> elements)
		{
			if (elements == null)
			{
				return false;
			}
			bool result = false;
			foreach (FilterType filterType in elements)
			{
				if (filterType.Type == OperatorType.Pipe || filterType.Type == OperatorType.Duct || filterType.Type == OperatorType.CableTray)
				{
					result = true;
					break;
				}
			}
			return result;
		}

		public static IList<FilterType> GetMaxGroup(IList<IList<FilterType>> groups)
		{
			int num = 0;
			IList<FilterType> result = new List<FilterType>();
			foreach (IList<FilterType> list in groups)
			{
				if (num < list.Count)
				{
					num = list.Count;
					result = list;
				}
			}
			return result;
		}

		public static IList<IList<BaseMark>> GetMarkInfo(IList<FilterType> elements, XYZ basePoint, int locateType)
		{
			IList<IList<BaseMark>> result = new List<IList<BaseMark>>();
			if (QuickMarkManager.ExistGridAndWall(elements))
			{
				result = QuickMarkManager.GetMarkInfoByType(elements, basePoint, locateType);
			}
			else
			{
				result = QuickMarkManager.GetMarkInfoNormal(elements, basePoint);
			}
			return result;
		}

		private static IList<IList<BaseMark>> GetMarkInfoByType(IList<FilterType> elements, XYZ basePoint, int locateType)
		{
			IList<IList<BaseMark>> result = null;
			switch (locateType)
			{
			case 0:
				result = QuickMarkManager.NearPriority(elements, basePoint);
				break;
			case 1:
				result = QuickMarkManager.GridPriority(elements, basePoint);
				break;
			case 2:
				result = QuickMarkManager.WallPriority(elements, basePoint);
				break;
			}
			return result;
		}

		private static IList<IList<BaseMark>> NearPriority(IList<FilterType> elements, XYZ basePoint)
		{
			if (elements == null || elements.Count < 2)
			{
				return null;
			}
			IList<IList<BaseMark>> list = new List<IList<BaseMark>>();
			List<BaseMark> list2 = new List<BaseMark>();
			FilterType filterType = null;
			for (int i = 0; i < elements.Count - 1; i++)
			{
				FilterType filterType2 = elements[i];
				FilterType filterType3 = elements[i + 1];
				if (filterType2.Type == OperatorType.Wall)
				{
					if (list2.Count > 0)
					{
						list.Add(list2);
						list2 = new List<BaseMark>();
					}
					if (filterType3.Type != OperatorType.Grid && filterType3.Type != OperatorType.Wall)
					{
						list2.Add(QuickMarkManager.GetSingleBaseMark(filterType2, basePoint, true));
						if (i == elements.Count - 2)
						{
							list2.AddRange(QuickMarkManager.GetBaseMark(filterType3, basePoint));
						}
					}
				}
				else if (filterType2.Type == OperatorType.Grid)
				{
					if (filterType3.Type == OperatorType.Wall || filterType3.Type == OperatorType.Grid)
					{
						if (list2.Count > 0)
						{
							list.Add(list2);
							list2 = new List<BaseMark>();
						}
					}
					else
					{
						if (filterType != filterType2)
						{
							list2.AddRange(QuickMarkManager.GetBaseMark(filterType2, basePoint));
							filterType = filterType2;
						}
						if (i == elements.Count - 2)
						{
							list2.AddRange(QuickMarkManager.GetBaseMark(filterType3, basePoint));
						}
					}
				}
				else
				{
					list2.AddRange(QuickMarkManager.GetBaseMark(filterType2, basePoint));
					if (filterType3.Type == OperatorType.Wall)
					{
						list2.Add(QuickMarkManager.GetSingleBaseMark(filterType3, basePoint, false));
					}
					else if (filterType3.Type == OperatorType.Grid)
					{
						list2.AddRange(QuickMarkManager.GetBaseMark(filterType3, basePoint));
						filterType = filterType3;
					}
					if (i == elements.Count - 2 && filterType3.Type != OperatorType.Wall && filterType3.Type != OperatorType.Grid)
					{
						list2.AddRange(QuickMarkManager.GetBaseMark(filterType3, basePoint));
					}
				}
			}
			if (list2.Count > 0)
			{
				list.Add(list2);
			}
			return list;
		}

		private static IList<MarkParameter> NearPriority1(IList<FilterType> elements, XYZ basePoint)
		{
			if (elements == null || elements.Count < 2)
			{
				return null;
			}
			IList<MarkParameter> list = new List<MarkParameter>();
			int i = 0;
			while (i < elements.Count - 1)
			{
				FilterType filterType = elements[i];
				FilterType filterType2 = elements[i + 1];
				if (filterType.Type == OperatorType.Wall && filterType2.Type != OperatorType.Wall)
				{
					if (filterType2.Type != OperatorType.Grid)
					{
						list.Add(new MarkParameter
						{
							Collection = 
							{
								QuickMarkManager.GetSingleBaseMark(filterType, basePoint, true),
								QuickMarkManager.GetSingleBaseMark(filterType2, basePoint, false)
							}
						});
						goto IL_162;
					}
				}
				else
				{
					if (filterType.Type == OperatorType.Duct || filterType.Type == OperatorType.CableTray)
					{
						MarkParameter markParameter = new MarkParameter();
						markParameter.Collection.Add(QuickMarkManager.GetSingleBaseMark(filterType, basePoint, false));
						BaseMark singleBaseMark = QuickMarkManager.GetSingleBaseMark(filterType, basePoint, true);
						markParameter.Collection.Add(singleBaseMark);
						list.Add(markParameter);
						list.Add(new MarkParameter
						{
							Collection = 
							{
								singleBaseMark,
								QuickMarkManager.GetSingleBaseMark(filterType2, basePoint, false)
							}
						});
						goto IL_162;
					}
					if (filterType.Type != OperatorType.Pipe && filterType.Type != OperatorType.Grid)
					{
						goto IL_162;
					}
					if (filterType.Type != OperatorType.Grid || filterType2.Type != OperatorType.Wall)
					{
						list.Add(new MarkParameter
						{
							Collection = 
							{
								QuickMarkManager.GetSingleBaseMark(filterType, basePoint, false),
								QuickMarkManager.GetSingleBaseMark(filterType2, basePoint, false)
							}
						});
						goto IL_162;
					}
				}
				IL_1B6:
				i++;
				continue;
				IL_162:
				if (i == elements.Count - 2 && (filterType2.Type == OperatorType.Duct || filterType2.Type == OperatorType.CableTray))
				{
					list.Add(new MarkParameter
					{
						Collection = 
						{
							QuickMarkManager.GetSingleBaseMark(filterType2, basePoint, false),
							QuickMarkManager.GetSingleBaseMark(filterType2, basePoint, true)
						}
					});
					goto IL_1B6;
				}
				goto IL_1B6;
			}
			return list;
		}

		private static IList<IList<BaseMark>> GridPriority(IList<FilterType> elements, XYZ basePoint)
		{
			if (elements == null || elements.Count < 2)
			{
				return null;
			}
			return QuickMarkManager.GetMarkInfoNormal(QuickMarkManager.RemoveElement(elements, OperatorType.Wall), basePoint);
		}

		private static IList<IList<BaseMark>> WallPriority(IList<FilterType> elements, XYZ basePoint)
		{
			if (elements == null || elements.Count < 2)
			{
				return null;
			}
			return QuickMarkManager.GetMarkInfoNormal(QuickMarkManager.RemoveElement(elements, OperatorType.Grid), basePoint);
		}

		private static void RemoveWallsNearGrid(IList<FilterType> elements)
		{
			if (elements == null)
			{
				return;
			}
			FilterType[] array = elements.ToArray<FilterType>();
			IList<FilterType> list = new List<FilterType>();
			IDictionary<int, FilterType> dictionary = new Dictionary<int, FilterType>();
			for (int i = 0; i < array.Length; i++)
			{
				if (array[i].Type == OperatorType.Grid)
				{
					dictionary.Add(i, array[i]);
				}
			}
			foreach (int num in dictionary.Keys)
			{
				if (num <= 0)
				{
					for (int j = num + 1; j < array.Length; j++)
					{
						if (array[j].Type != OperatorType.Wall)
						{
							break;
						}
						if (!list.Contains(array[j]))
						{
							list.Add(array[j]);
						}
					}
				}
				else
				{
					int num2 = num - 1;
					while (num2 >= 0 && array[num2].Type == OperatorType.Wall)
					{
						if (!list.Contains(array[num2]))
						{
							list.Add(array[num2]);
						}
						num2--;
					}
					int num3 = num + 1;
					while (num3 < array.Length && array[num3].Type == OperatorType.Wall)
					{
						if (!list.Contains(array[num3]))
						{
							list.Add(array[num3]);
						}
						num3++;
					}
				}
			}
			foreach (FilterType item in list)
			{
				elements.Remove(item);
			}
		}

		private static void RemoveGridsNearWall(IList<FilterType> elements)
		{
			if (elements == null)
			{
				return;
			}
			FilterType[] array = elements.ToArray<FilterType>();
			IList<FilterType> list = new List<FilterType>();
			IDictionary<int, FilterType> dictionary = new Dictionary<int, FilterType>();
			for (int i = 0; i < array.Length; i++)
			{
				if (array[i].Type == OperatorType.Wall)
				{
					dictionary.Add(i, array[i]);
				}
			}
			foreach (int num in dictionary.Keys)
			{
				if (num <= 0)
				{
					for (int j = num + 1; j < array.Length; j++)
					{
						if (array[j].Type != OperatorType.Grid)
						{
							break;
						}
						if (!list.Contains(array[j]))
						{
							list.Add(array[j]);
						}
					}
				}
				else
				{
					int num2 = num - 1;
					while (num2 >= 0 && array[num2].Type == OperatorType.Grid)
					{
						if (!list.Contains(array[num2]))
						{
							list.Add(array[num2]);
						}
						num2--;
					}
					int num3 = num + 1;
					while (num3 < array.Length && array[num3].Type == OperatorType.Grid)
					{
						if (!list.Contains(array[num3]))
						{
							list.Add(array[num3]);
						}
						num3++;
					}
				}
			}
			foreach (FilterType item in list)
			{
				elements.Remove(item);
			}
		}

		private static IList<FilterType> RemoveElement(IList<FilterType> elements, OperatorType operType)
		{
			if (elements == null)
			{
				return elements;
			}
			IList<FilterType> list = new List<FilterType>();
			foreach (FilterType filterType in elements)
			{
				if (filterType.Type != operType)
				{
					list.Add(filterType);
				}
			}
			return list;
		}

		public static IList<IList<BaseMark>> GetMarkInfoNormal(IList<FilterType> elements, XYZ basePoint)
		{
			if (elements == null || elements.Count < 2)
			{
				return null;
			}
			IList<IList<BaseMark>> list = new List<IList<BaseMark>>();
			List<BaseMark> list2 = new List<BaseMark>();
			FilterType filterType = null;
			for (int i = 0; i < elements.Count - 1; i++)
			{
				FilterType filterType2 = elements[i];
				FilterType filterType3 = elements[i + 1];
				if (filterType2.Type == OperatorType.Wall)
				{
					if (list2.Count > 0)
					{
						list.Add(list2);
						list2 = new List<BaseMark>();
					}
					if (filterType3.Type != filterType2.Type)
					{
						list2.Add(QuickMarkManager.GetSingleBaseMark(filterType2, basePoint, true));
						if (i == elements.Count - 2)
						{
							list2.AddRange(QuickMarkManager.GetBaseMark(filterType3, basePoint));
						}
					}
				}
				else if (filterType2.Type == OperatorType.Grid)
				{
					if (filterType2.Type == filterType3.Type)
					{
						if (list2.Count > 0)
						{
							list.Add(list2);
							list2 = new List<BaseMark>();
						}
					}
					else if (filterType != filterType2)
					{
						list2.AddRange(QuickMarkManager.GetBaseMark(filterType2, basePoint));
						filterType = filterType2;
					}
					if (i == elements.Count - 2 && filterType3.Type != OperatorType.Grid)
					{
						list2.AddRange(QuickMarkManager.GetBaseMark(filterType3, basePoint));
					}
				}
				else
				{
					list2.AddRange(QuickMarkManager.GetBaseMark(filterType2, basePoint));
					if (filterType3.Type == OperatorType.Wall)
					{
						list2.Add(QuickMarkManager.GetSingleBaseMark(filterType3, basePoint, false));
					}
					else if (filterType3.Type == OperatorType.Grid)
					{
						list2.AddRange(QuickMarkManager.GetBaseMark(filterType3, basePoint));
						filterType = filterType3;
					}
					if (i == elements.Count - 2 && filterType3.Type != OperatorType.Wall && filterType3.Type != OperatorType.Grid)
					{
						list2.AddRange(QuickMarkManager.GetBaseMark(filterType3, basePoint));
					}
				}
			}
			if (list2.Count > 0)
			{
				list.Add(list2);
			}
			return list;
		}

		public static IList<MarkParameter> GetMarkInfoNormal1(IList<FilterType> elements, XYZ basePoint)
		{
			if (elements == null || elements.Count < 2)
			{
				return null;
			}
			IList<MarkParameter> list = new List<MarkParameter>();
			for (int i = 0; i < elements.Count - 1; i++)
			{
				FilterType filterType = elements[i];
				FilterType filterType2 = elements[i + 1];
				if (filterType.Type == OperatorType.Wall && filterType2.Type != OperatorType.Wall)
				{
					list.Add(new MarkParameter
					{
						Collection = 
						{
							QuickMarkManager.GetSingleBaseMark(filterType, basePoint, true),
							QuickMarkManager.GetSingleBaseMark(filterType2, basePoint, false)
						}
					});
				}
				else if (filterType.Type == OperatorType.Duct || filterType.Type == OperatorType.CableTray)
				{
					MarkParameter markParameter = new MarkParameter();
					markParameter.Collection.Add(QuickMarkManager.GetSingleBaseMark(filterType, basePoint, false));
					BaseMark singleBaseMark = QuickMarkManager.GetSingleBaseMark(filterType, basePoint, true);
					markParameter.Collection.Add(singleBaseMark);
					list.Add(markParameter);
					list.Add(new MarkParameter
					{
						Collection = 
						{
							singleBaseMark,
							QuickMarkManager.GetSingleBaseMark(filterType2, basePoint, false)
						}
					});
				}
				else if (filterType.Type == OperatorType.Pipe || filterType.Type == OperatorType.Grid)
				{
					list.Add(new MarkParameter
					{
						Collection = 
						{
							QuickMarkManager.GetSingleBaseMark(filterType, basePoint, false),
							QuickMarkManager.GetSingleBaseMark(filterType2, basePoint, false)
						}
					});
				}
				if (i == elements.Count - 2 && (filterType2.Type == OperatorType.Duct || filterType2.Type == OperatorType.CableTray))
				{
					list.Add(new MarkParameter
					{
						Collection = 
						{
							QuickMarkManager.GetSingleBaseMark(filterType2, basePoint, false),
							QuickMarkManager.GetSingleBaseMark(filterType2, basePoint, true)
						}
					});
				}
			}
			return list;
		}

		public static IList<BaseMark> GetBaseMark(FilterType item, XYZ basePoint)
		{
			if (item == null)
			{
				return null;
			}
			YJKLine line = item.Line;
			line.MakeUnBound();
			XYZ project = line.GetProject(basePoint);
			XYZ xyz = project.Subtract(basePoint).Normalize();
			IList<BaseMark> list = new List<BaseMark>();
			switch (item.Type)
			{
			case OperatorType.Wall:
			{
				double num = (item.Element as Wall).Width;
				list.Add(new BaseMark
				{
					PPoint = project.Add(num / 2.0 * -xyz),
					Line = new YJKLine(line.StartPoint.Add(num / 2.0 * -xyz), line.EndPoint.Add(num / 2.0 * -xyz)),
					element = item.Element,
					IsLinkedElement = item.IsLinkedElement
				});
				list.Add(new BaseMark
				{
					PPoint = project.Add(num / 2.0 * xyz),
					Line = new YJKLine(line.StartPoint.Add(num / 2.0 * xyz), line.EndPoint.Add(num / 2.0 * xyz)),
					element = item.Element,
					IsLinkedElement = item.IsLinkedElement
				});
				break;
			}
			case OperatorType.Grid:
			case OperatorType.Pipe:
				list.Add(new BaseMark
				{
					PPoint = project,
					Line = line,
					element = item.Element,
					IsLinkedElement = item.IsLinkedElement
				});
				break;
			case OperatorType.CableTray:
			{
				double num = (item.Element as CableTray).Width;
				list.Add(new BaseMark
				{
					PPoint = project.Add(num / 2.0 * -xyz),
					Line = new YJKLine(line.StartPoint.Add(num / 2.0 * -xyz), line.EndPoint.Add(num / 2.0 * -xyz)),
					element = item.Element,
					IsLinkedElement = item.IsLinkedElement
				});
				list.Add(new BaseMark
				{
					PPoint = project.Add(num / 2.0 * xyz),
					Line = new YJKLine(line.StartPoint.Add(num / 2.0 * xyz), line.EndPoint.Add(num / 2.0 * xyz)),
					element = item.Element,
					IsLinkedElement = item.IsLinkedElement
				});
				break;
			}
			case OperatorType.Duct:
			{
				double num = YJKRevitTools.getDuctWidth(item.Element as Duct);
				list.Add(new BaseMark
				{
					PPoint = project.Add(num / 2.0 * -xyz),
					Line = new YJKLine(line.StartPoint.Add(num / 2.0 * -xyz), line.EndPoint.Add(num / 2.0 * -xyz)),
					element = item.Element,
					IsLinkedElement = item.IsLinkedElement
				});
				list.Add(new BaseMark
				{
					PPoint = project.Add(num / 2.0 * xyz),
					Line = new YJKLine(line.StartPoint.Add(num / 2.0 * xyz), line.EndPoint.Add(num / 2.0 * xyz)),
					element = item.Element,
					IsLinkedElement = item.IsLinkedElement
				});
				break;
			}
			}
			return list;
		}

		public static BaseMark GetSingleBaseMark(FilterType item, XYZ basePoint, bool sameVector = false)
		{
			if (item == null)
			{
				return null;
			}
			YJKLine line = item.Line;
			line.MakeUnBound();
			XYZ project = line.GetProject(basePoint);
			XYZ xyz = project.Subtract(basePoint).Normalize();
			BaseMark baseMark = new BaseMark();
			baseMark.element = item.Element;
			baseMark.IsLinkedElement = item.IsLinkedElement;
			switch (item.Type)
			{
			case OperatorType.Wall:
			{
				double num = (item.Element as Wall).Width;
				if (sameVector)
				{
					baseMark.PPoint = project.Add(num / 2.0 * xyz);
					baseMark.Line = new YJKLine(line.StartPoint.Add(num / 2.0 * xyz), line.EndPoint.Add(num / 2.0 * xyz));
				}
				else
				{
					baseMark.PPoint = project.Add(num / 2.0 * -xyz);
					baseMark.Line = new YJKLine(line.StartPoint.Add(num / 2.0 * -xyz), line.EndPoint.Add(num / 2.0 * -xyz));
				}
				break;
			}
			case OperatorType.Grid:
			case OperatorType.Pipe:
				baseMark.PPoint = project;
				baseMark.Line = line;
				break;
			case OperatorType.CableTray:
			{
				double num = (item.Element as CableTray).Width;
				if (sameVector)
				{
					baseMark.PPoint = project.Add(num / 2.0 * xyz);
					baseMark.Line = new YJKLine(line.StartPoint.Add(num / 2.0 * xyz), line.EndPoint.Add(num / 2.0 * xyz));
				}
				else
				{
					baseMark.PPoint = project.Add(num / 2.0 * -xyz);
					baseMark.Line = new YJKLine(line.StartPoint.Add(num / 2.0 * -xyz), line.EndPoint.Add(num / 2.0 * -xyz));
				}
				break;
			}
			case OperatorType.Duct:
			{
				double num = YJKRevitTools.getDuctWidth(item.Element as Duct);
				if (sameVector)
				{
					baseMark.PPoint = project.Add(num / 2.0 * xyz);
					baseMark.Line = new YJKLine(line.StartPoint.Add(num / 2.0 * xyz), line.EndPoint.Add(num / 2.0 * xyz));
				}
				else
				{
					baseMark.PPoint = project.Add(num / 2.0 * -xyz);
					baseMark.Line = new YJKLine(line.StartPoint.Add(num / 2.0 * -xyz), line.EndPoint.Add(num / 2.0 * -xyz));
				}
				break;
			}
			}
			return baseMark;
		}

		public static bool ExistGridAndWall(IList<FilterType> elements)
		{
			if (elements == null || elements.Count < 2)
			{
				return false;
			}
			bool flag = false;
			bool flag2 = false;
			foreach (FilterType filterType in elements)
			{
				if (filterType.Type == OperatorType.Grid)
				{
					flag = true;
				}
				else if (filterType.Type == OperatorType.Wall)
				{
					flag2 = true;
				}
			}
			return flag && flag2;
		}

		public static IList<FilterType> GetElementByTwoPoint(Autodesk.Revit.DB.Document document, XYZ pStartPoint, XYZ pEndPoint, Plane workPlane)
		{
			ElementClassFilter item = new ElementClassFilter(typeof(Pipe));
			ElementClassFilter item2 = new ElementClassFilter(typeof(Duct));
			ElementClassFilter item3 = new ElementClassFilter(typeof(CableTray));
			ElementClassFilter item4 = new ElementClassFilter(typeof(Grid));
			ElementClassFilter item5 = new ElementClassFilter(typeof(Wall));
			LogicalOrFilter filter = new LogicalOrFilter(new List<ElementFilter>
			{
				item,
				item2,
				item3,
				item4,
				item5
			});
			List<BaseLinkDocumentResultBean> list = new FilteredElementCollectorLinkDocument(document).WherePass(filter).ToBeans();
			double[] viewRange = RevitAPIUIOperate.GetViewRange2(document.ActiveView, false);
			List<BaseLinkDocumentResultBean> list2 = new List<BaseLinkDocumentResultBean>();
			foreach (BaseLinkDocumentResultBean baseLinkDocumentResultBean in list)
			{
				LocationCurve locationCurve = baseLinkDocumentResultBean.UseElement.Location as LocationCurve;
				Curve curve = null;
				if (locationCurve == null)
				{
					if (baseLinkDocumentResultBean.UseElement is Grid)
					{
						list2.Add(baseLinkDocumentResultBean);
					}
				}
				else
				{
					curve = locationCurve.Curve;
				}
				if (curve != null)
				{
					double num = Math.Round(curve.GetEndPoint(0).Z, 3, MidpointRounding.AwayFromZero);
					double num2 = Math.Round(curve.GetEndPoint(1).Z, 3, MidpointRounding.AwayFromZero);
					viewRange[0] = Math.Round(viewRange[0], 3, MidpointRounding.AwayFromZero);
					viewRange[1] = Math.Round(viewRange[1], 3, MidpointRounding.AwayFromZero);
					if ((num >= viewRange[0] && num < viewRange[1]) || (num2 >= viewRange[0] && num2 < viewRange[1]))
					{
						list2.Add(baseLinkDocumentResultBean);
					}
				}
			}
			OperatorType type = OperatorType.Undefined;
			IList<FilterType> list3 = new List<FilterType>();
			foreach (BaseLinkDocumentResultBean baseLinkDocumentResultBean2 in list2)
			{
				Curve curve2 = null;
				Element useElement = baseLinkDocumentResultBean2.UseElement;
				bool isLinkedElement;
				if (baseLinkDocumentResultBean2.UseLinkeInstance == null)
				{
					isLinkedElement = false;
					if (useElement is Pipe)
					{
						Pipe pipe = useElement as Pipe;
						if (pipe.IsHidden(document.ActiveView))
						{
							continue;
						}
						type = OperatorType.Pipe;
						curve2 = (pipe.Location as LocationCurve).Curve;
					}
					else if (useElement is Duct)
					{
						Duct duct = useElement as Duct;
						if (duct.IsHidden(document.ActiveView))
						{
							continue;
						}
						type = OperatorType.Duct;
						curve2 = (duct.Location as LocationCurve).Curve;
					}
					else if (useElement is CableTray)
					{
						CableTray cableTray = useElement as CableTray;
						if (cableTray.IsHidden(document.ActiveView))
						{
							continue;
						}
						type = OperatorType.CableTray;
						curve2 = (cableTray.Location as LocationCurve).Curve;
					}
					else if (useElement is Grid)
					{
						Grid grid = useElement as Grid;
						if (grid.IsHidden(document.ActiveView))
						{
							continue;
						}
						type = OperatorType.Grid;
						curve2 = grid.Curve;
					}
					else if (useElement is Wall)
					{
						Wall wall = useElement as Wall;
						if (wall.IsHidden(document.ActiveView))
						{
							continue;
						}
						type = OperatorType.Wall;
						curve2 = (wall.Location as LocationCurve).Curve;
					}
				}
				else
				{
					isLinkedElement = true;
					Transform totalTransform = baseLinkDocumentResultBean2.GetTotalTransform();
					if (totalTransform == null)
					{
						continue;
					}
					if (useElement is Pipe)
					{
						Pipe pipe2 = useElement as Pipe;
						if (pipe2.IsHidden(document.ActiveView))
						{
							continue;
						}
						type = OperatorType.Pipe;
						curve2 = (pipe2.Location as LocationCurve).Curve;
					}
					else if (useElement is Duct)
					{
						Duct duct2 = useElement as Duct;
						if (duct2.IsHidden(document.ActiveView))
						{
							continue;
						}
						type = OperatorType.Duct;
						curve2 = (duct2.Location as LocationCurve).Curve;
					}
					else if (useElement is CableTray)
					{
						CableTray cableTray2 = useElement as CableTray;
						if (cableTray2.IsHidden(document.ActiveView))
						{
							continue;
						}
						type = OperatorType.CableTray;
						curve2 = (cableTray2.Location as LocationCurve).Curve;
					}
					else if (useElement is Grid)
					{
						Grid grid2 = useElement as Grid;
						if (grid2.IsHidden(document.ActiveView))
						{
							continue;
						}
						type = OperatorType.Grid;
						curve2 = grid2.Curve;
					}
					else if (useElement is Wall)
					{
						Wall wall2 = useElement as Wall;
						if (wall2.IsHidden(document.ActiveView))
						{
							continue;
						}
						type = OperatorType.Wall;
						curve2 = (wall2.Location as LocationCurve).Curve;
					}
					curve2 = curve2.CreateTransformed(totalTransform);
				}
				YJKLine hyline = new YJKLine(QuickMarkManager.GetProject(pStartPoint, workPlane), QuickMarkManager.GetProject(pEndPoint, workPlane));
				XYZ project = QuickMarkManager.GetProject(curve2.GetEndPoint(0), workPlane);
				XYZ project2 = QuickMarkManager.GetProject(curve2.GetEndPoint(1), workPlane);
				if (!project.IsAlmostEqualTo(project2, 0.001))
				{
					YJKLine hyline2 = new YJKLine(project, project2);
					if (!(hyline2.Line == null) && hyline.IntersectionPoint(hyline2.Line) != null)
					{
						list3.Add(new FilterType
						{
							Element = useElement,
							Line = hyline2,
							Type = type,
							IsLinkedElement = isLinkedElement
						});
					}
				}
			}
			return list3;
		}

		public static XYZ GetProject(XYZ p, Plane plane)
		{
			if (plane == null)
			{
				return null;
			}
			XYZ origin = plane.Origin;
			XYZ xvec = plane.XVec;
			XYZ yvec = plane.YVec;
			XYZ normal = plane.Normal;
			double num = (normal.X * normal.Y * origin.Y + normal.Y * normal.Y * p.X - normal.X * normal.Y * p.Y + normal.X * normal.Z * origin.Z + normal.Z * normal.Z * p.X - normal.X * normal.Z * p.Z + normal.X * normal.X * origin.X) / (normal.X * normal.X + normal.Y * normal.Y + normal.Z * normal.Z);
			double num2 = (normal.Y * normal.Z * origin.Z + normal.Z * normal.Z * p.Y - normal.Y * normal.Z * p.Z + normal.Y * normal.X * origin.X + normal.X * normal.X * p.Y - normal.X * normal.Y * p.X + normal.Y * normal.Y * origin.Y) / (normal.X * normal.X + normal.Y * normal.Y + normal.Z * normal.Z);
			double num3 = (normal.X * origin.X * normal.Z + normal.X * normal.X * p.Z - normal.X * p.X * normal.Z + normal.Y * origin.Y * normal.Z + normal.Y * normal.Y * p.Z - normal.Y * p.Y * normal.Z + normal.Z * normal.Z * origin.Z) / (normal.X * normal.X + normal.Y * normal.Y + normal.Z * normal.Z);
			return new XYZ(num, num2, num3);
		}

		public static IList<IList<FilterType>> FilterParallelPipes(IList<FilterType> elements)
		{
			IList<IList<FilterType>> list = new List<IList<FilterType>>();
			IList<FilterType> list2 = new List<FilterType>();
			for (int i = 0; i < elements.Count - 1; i++)
			{
				if (!list2.Contains(elements[i]))
				{
					IList<FilterType> list3 = new List<FilterType>();
					list3.Add(elements[i]);
					list2.Add(elements[i]);
					for (int j = i + 1; j < elements.Count; j++)
					{
						if (elements[i].Line.IsParallel(elements[j].Line.Line))
						{
							list3.Add(elements[j]);
							list2.Add(elements[j]);
						}
					}
					list.Add(list3);
				}
			}
			return list;
		}

		public static void Sort(IList<FilterType> list, XYZ pEndPOint)
		{
			for (int i = 0; i < list.Count - 1; i++)
			{
				for (int j = i + 1; j < list.Count; j++)
				{
					double distance = QuickMarkManager.GetDistance(list[i].Line, pEndPOint);
					double distance2 = QuickMarkManager.GetDistance(list[j].Line, pEndPOint);
					if (distance > distance2)
					{
						FilterType value = list[i];
						list[i] = list[j];
						list[j] = value;
					}
				}
			}
		}

		public static double GetDistance(YJKLine line, XYZ Point)
		{
			return line.GetProject(Point).DistanceTo(Point) * 304.8;
		}

		public static double GetDistance(FilterType filterType, XYZ point)
		{
			XYZ xyz = null;
			YJKLine line = filterType.Line;
			line.MakeUnBound();
			XYZ project = line.GetProject(point);
			XYZ xyz2 = project.Subtract(point).Normalize();
			switch (filterType.Type)
			{
			case OperatorType.Wall:
			{
				double num = (filterType.Element as Wall).Width;
				xyz = project.Add(num / 2.0 * -xyz2);
				break;
			}
			case OperatorType.Grid:
				xyz = project;
				break;
			case OperatorType.CableTray:
			{
				double num = (filterType.Element as CableTray).Width;
				xyz = project.Add(num / 2.0 * -xyz2);
				break;
			}
			case OperatorType.Pipe:
			{
				double num = new YJKPiping<Pipe>(filterType.Element as Pipe).GetWeightOrDiameter();
				xyz = project.Add(num / 2.0 * -xyz2);
				break;
			}
			case OperatorType.Duct:
			{
				double num = YJKRevitTools.getDuctWidth(filterType.Element as Duct);
				xyz = project.Add(num / 2.0 * -xyz2);
				break;
			}
			}
			return point.DistanceTo(xyz) * 304.8;
		}

		private static double GetAngle(Line line1, Line line2)
		{
			double result;
			try
			{
				double num = line1.Direction.AngleOnPlaneTo(line2.Direction, XYZ.BasisZ) * 180.0 / Math.PI;
				if (Math.Abs(360.0 - num) < 0.001)
				{
					num = Math.Abs(num - 360.0);
				}
				if (Math.Abs(180.0 - num) < 0.001)
				{
					num = Math.Abs(num - 180.0);
				}
				if ((num > 0.0 && num < 5.0) || (num < 360.0 && num > 355.0))
				{
					num = 0.0;
				}
				result = num;
			}
			catch
			{
				result = 0.0;
			}
			return result;
		}

		public static void StoreData(Element element, IDictionary<string, string> data, bool isAppend = true)
		{
			Schema schema = Schema.Lookup(new Guid("720080CB-DA99-40DC-9415-E53F280AA1F0"));
			if (schema == null)
			{
				SchemaBuilder schemaBuilder = new SchemaBuilder(new Guid("720080CB-DA99-40DC-9415-E53F280AA1F0"));
				schemaBuilder.SetReadAccessLevel((AccessLevel)1);
				schemaBuilder.SetWriteAccessLevel((AccessLevel)1);
				schemaBuilder.SetVendorId("ASDK");
				schemaBuilder.AddMapField("filterMark", typeof(string), typeof(string));
				schemaBuilder.SetSchemaName("FilterMark");
				schema = schemaBuilder.Finish();
			}
			Entity entity = element.GetEntity(schema);
			if (entity == null || entity.Schema == null)
			{
				entity = new Entity(schema);
			}
			Field field = schema.GetField("filterMark");
			if (field != null && entity != null && isAppend)
			{
				IDictionary<string, string> dictionary = entity.Get<IDictionary<string, string>>(field);
				if (dictionary != null && dictionary.Count > 0)
				{
					string key = dictionary.Keys.FirstOrDefault<string>();
					string text = dictionary[key];
					string key2 = data.Keys.FirstOrDefault<string>();
					string text2 = data[key2];
					string value = string.Join(",", new string[]
					{
						text,
						text2
					});
					data[key2] = value;
				}
			}
			entity.Set<IDictionary<string, string>>(field, data);
			element.SetEntity(entity);
		}

		public static string PointToString(XYZ xyz)
		{
			string empty = string.Empty;
			if (xyz == null)
			{
				return empty;
			}
			return string.Format("{0},{1},{2}", xyz.X, xyz.Y, xyz.Z);
		}

		public static void RemoveIntersected(IList<FilterType> eleList, XYZ basePoint, Autodesk.Revit.DB.Document doc, int locateType)
		{
			if (eleList == null)
			{
				return;
			}
			IList<FilterType> list = (from x in eleList
			where x.Type == OperatorType.Grid
			select x).ToList<FilterType>();
			IList<FilterType> list2 = (from x in eleList
			where x.Type == OperatorType.Pipe
			select x).ToList<FilterType>();
			IList<FilterType> list3 = (from x in eleList
			where x.Type == OperatorType.Wall
			select x).ToList<FilterType>();
			IList<FilterType> list4 = (from x in eleList
			where x.Type == OperatorType.Duct
			select x).ToList<FilterType>();
			IList<FilterType> list5 = (from x in eleList
			where x.Type == OperatorType.CableTray
			select x).ToList<FilterType>();
			IList<FilterType> list6 = new List<FilterType>();
			if (list2.Count > 1)
			{
				for (int i = 0; i < list2.Count; i++)
				{
					for (int j = i + 1; j < list2.Count; j++)
					{
						if (list2[i].Line.IsLineOnLine(list2[j].Line.Line) && !list6.Contains(list2[j]))
						{
							list6.Add(list2[j]);
						}
					}
				}
				IEnumerator<FilterType> enumerator = list6.GetEnumerator();
				{
					while (enumerator.MoveNext())
					{
						FilterType item = enumerator.Current;
						eleList.Remove(eleList.FirstOrDefault((FilterType x) => x == item));
					}
				}
			}
			if (list.Count > 1)
			{
				list6.Clear();
				for (int k = 0; k < list.Count; k++)
				{
					for (int l = k + 1; l < list.Count; l++)
					{
						if (list[k].Line.IsLineOnLine(list[l].Line.Line) && !list6.Contains(list[l]))
						{
							list6.Add(list[l]);
						}
					}
				}
				IEnumerator<FilterType> enumerator = list6.GetEnumerator();
				{
					while (enumerator.MoveNext())
					{
						FilterType item = enumerator.Current;
						eleList.Remove(eleList.FirstOrDefault((FilterType x) => x == item));
					}
				}
			}
			if (list4.Count > 1)
			{
				list6.Clear();
				for (int m = 0; m < list4.Count; m++)
				{
					for (int n = m + 1; n < list4.Count; n++)
					{
						if (list4[m].Line.IsLineOnLine(list4[n].Line.Line) && !list6.Contains(list4[n]))
						{
							list6.Add(list4[n]);
						}
					}
				}
				IEnumerator<FilterType> enumerator = list6.GetEnumerator();
				{
					while (enumerator.MoveNext())
					{
						FilterType item = enumerator.Current;
						eleList.Remove(eleList.FirstOrDefault((FilterType x) => x == item));
					}
				}
			}
			if (list3.Count > 1)
			{
				list6.Clear();
				for (int num = 0; num < list3.Count; num++)
				{
					for (int num2 = num + 1; num2 < list3.Count; num2++)
					{
						if (list3[num].Line.IsLineOnLine(list3[num2].Line.Line) && !list6.Contains(list3[num2]))
						{
							list6.Add(list3[num2]);
						}
					}
				}
				IEnumerator<FilterType> enumerator = list6.GetEnumerator();
				{
					while (enumerator.MoveNext())
					{
						FilterType item = enumerator.Current;
						eleList.Remove(eleList.FirstOrDefault((FilterType x) => x == item));
					}
				}
			}
			if (list5.Count > 1)
			{
				list6.Clear();
				for (int num3 = 0; num3 < list5.Count; num3++)
				{
					for (int num4 = num3 + 1; num4 < list5.Count; num4++)
					{
						if (list5[num3].Line.IsLineOnLine(list5[num4].Line.Line) && !list6.Contains(list5[num4]))
						{
							list6.Add(list5[num4]);
						}
					}
				}
				IEnumerator<FilterType> enumerator = list6.GetEnumerator();
				{
					while (enumerator.MoveNext())
					{
						FilterType item = enumerator.Current;
						eleList.Remove(eleList.FirstOrDefault((FilterType x) => x == item));
					}
				}
			}
			if (locateType == 0)
			{
				foreach (FilterType filterType in (from x in eleList
				where x.Type == OperatorType.Wall
				select x).ToList<FilterType>())
				{
					double num5 = (filterType.Element as Wall).Width;
					YJKLine line = filterType.Line;
					XYZ xyz = (line.StartPoint + line.EndPoint) / 2.0;
					line.MakeUnBound();
					XYZ xyz2 = line.GetProject(basePoint).Subtract(basePoint).Normalize();
					XYZ start = xyz.Add(num5 / 2.0 * -xyz2);
					XYZ end = xyz.Add(num5 / 2.0 * xyz2);
					YJKLine hyline = new YJKLine(start, end);
					using (List<FilterType>.Enumerator enumerator3 = (from x in eleList
					where x.Type == OperatorType.Grid
					select x).ToList<FilterType>().GetEnumerator())
					{
						while (enumerator3.MoveNext())
						{
							FilterType gridItem = enumerator3.Current;
							if (hyline.IntersectionPoint(gridItem.Line.Line) != null)
							{
								eleList.Remove(eleList.FirstOrDefault((FilterType x) => x.Element == gridItem.Element));
							}
						}
					}
				}
			}
			using (List<FilterType>.Enumerator enumerator2 = (from x in eleList
			where x.Type == OperatorType.Duct
			select x).ToList<FilterType>().GetEnumerator())
			{
				while (enumerator2.MoveNext())
				{
					FilterType item = enumerator2.Current;
					double num5 = YJKRevitTools.GetDuctWidthorDiameter(item.Element as Duct);
					YJKLine line2 = item.Line;
					XYZ xyz3 = (line2.StartPoint + line2.EndPoint) / 2.0;
					line2.MakeUnBound();
					XYZ xyz4 = line2.GetProject(basePoint).Subtract(basePoint).Normalize();
					XYZ start2 = xyz3.Add(num5 / 2.0 * -xyz4);
					XYZ end2 = xyz3.Add(num5 / 2.0 * xyz4);
					YJKLine hyline2 = new YJKLine(start2, end2);
					using (List<FilterType>.Enumerator enumerator3 = (from x in eleList
					where x.Type == OperatorType.Grid
					select x).ToList<FilterType>().GetEnumerator())
					{
						while (enumerator3.MoveNext())
						{
							FilterType gridItem = enumerator3.Current;
							if (hyline2.IntersectionPoint(gridItem.Line.Line) != null)
							{
								eleList.Remove(eleList.FirstOrDefault((FilterType x) => x.Element == gridItem.Element));
							}
						}
					}
					using (List<FilterType>.Enumerator enumerator3 = (from x in eleList
					where x.Type == OperatorType.Pipe
					select x).ToList<FilterType>().GetEnumerator())
					{
						while (enumerator3.MoveNext())
						{
							FilterType pipeItem = enumerator3.Current;
							if (hyline2.IntersectionPoint(pipeItem.Line.Line) != null)
							{
								eleList.Remove(eleList.FirstOrDefault((FilterType x) => x.Element == pipeItem.Element));
							}
						}
					}
					Func<FilterType, bool> predicate;
                    Func<FilterType, bool> ss9__18 = null;
					if ((predicate = ss9__18) == null)
					{
						predicate = (ss9__18 = ((FilterType x) => x.Type == OperatorType.Duct && x.Element != item.Element));
					}
					using (List<FilterType>.Enumerator enumerator3 = eleList.Where(predicate).ToList<FilterType>().GetEnumerator())
					{
						while (enumerator3.MoveNext())
						{
							FilterType ductItem = enumerator3.Current;
							if (hyline2.IntersectionPoint(ductItem.Line.Line) != null)
							{
								eleList.Remove(eleList.FirstOrDefault((FilterType x) => x.Element == ductItem.Element));
							}
						}
					}
				}
			}
			using (List<FilterType>.Enumerator enumerator2 = (from x in eleList
			where x.Type == OperatorType.CableTray
			select x).ToList<FilterType>().GetEnumerator())
			{
				while (enumerator2.MoveNext())
				{
					FilterType item = enumerator2.Current;
					double num5 = (item.Element as CableTray).Width;
					YJKLine line3 = item.Line;
					XYZ xyz5 = (line3.StartPoint + line3.EndPoint) / 2.0;
					line3.MakeUnBound();
					XYZ xyz6 = line3.GetProject(basePoint).Subtract(basePoint).Normalize();
					XYZ start3 = xyz5.Add(num5 / 2.0 * -xyz6);
					XYZ end3 = xyz5.Add(num5 / 2.0 * xyz6);
					YJKLine hyline3 = new YJKLine(start3, end3);
					using (List<FilterType>.Enumerator enumerator3 = (from x in eleList
					where x.Type == OperatorType.Grid
					select x).ToList<FilterType>().GetEnumerator())
					{
						while (enumerator3.MoveNext())
						{
							FilterType gridItem = enumerator3.Current;
							if (hyline3.IntersectionPoint(gridItem.Line.Line) != null)
							{
								eleList.Remove(eleList.FirstOrDefault((FilterType x) => x.Element == gridItem.Element));
							}
						}
					}
					using (List<FilterType>.Enumerator enumerator3 = (from x in eleList
					where x.Type == OperatorType.Pipe
					select x).ToList<FilterType>().GetEnumerator())
					{
						while (enumerator3.MoveNext())
						{
							FilterType pipeItem = enumerator3.Current;
							if (hyline3.IntersectionPoint(pipeItem.Line.Line) != null)
							{
								eleList.Remove(eleList.FirstOrDefault((FilterType x) => x.Element == pipeItem.Element));
							}
						}
					}
					using (List<FilterType>.Enumerator enumerator3 = (from x in eleList
					where x.Type == OperatorType.Duct
					select x).ToList<FilterType>().GetEnumerator())
					{
						while (enumerator3.MoveNext())
						{
							FilterType ductItem = enumerator3.Current;
							if (hyline3.IntersectionPoint(ductItem.Line.Line) != null)
							{
								eleList.Remove(eleList.FirstOrDefault((FilterType x) => x.Element == ductItem.Element));
							}
						}
					}
					Func<FilterType, bool> predicate2;
					Func<FilterType, bool> ss9__27 = null;
					if ((predicate2 = ss9__27) == null)
					{
						predicate2 = (ss9__27 = ((FilterType x) => x.Type == OperatorType.CableTray && x.Element != item.Element));
					}
					using (List<FilterType>.Enumerator enumerator3 = eleList.Where(predicate2).ToList<FilterType>().GetEnumerator())
					{
						while (enumerator3.MoveNext())
						{
							FilterType cabTrayItem = enumerator3.Current;
							if (hyline3.IntersectionPoint(cabTrayItem.Line.Line) != null)
							{
								eleList.Remove(eleList.FirstOrDefault((FilterType x) => x.Element == cabTrayItem.Element));
							}
						}
					}
				}
			}
		}
	}
}
